package moriarty.gwt.client;

import java.util.Date;
import java.util.List;

import moriarty.gwt.shared.Group;

import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;

/**
 * Singleton Class for the All Groups Tab
 * @author cmoriarty
 *
 */
public class AllGroupsTab extends Composite{

	private static AllGroupsTab instance = null;	
	private ListDataProvider<Group> dataProvider;
	private final SotdServiceAsync sotdService = GWT.create(SotdService.class);

	public static AllGroupsTab getInstance(){
	     if(instance == null) {
	         instance = new AllGroupsTab();
	      }
	      return instance;
	}
	
	protected AllGroupsTab(){
		init();
	}
	
	private void init(){
		final VerticalPanel allPanel = new VerticalPanel();
		Button addGroupButton = new Button("+ Add Group");
		addGroupButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// Create the dialog box
			    final DialogBox dialogBox = createDialogBox();
			    dialogBox.setGlassEnabled(true);
			    dialogBox.setAnimationEnabled(true);
			    dialogBox.show();
				dialogBox.center();
			}
		});		
		allPanel.add(addGroupButton);	
		
		
		final CellTable<Group> cellTable = new CellTable<Group>();
		
	    // Create a data provider.
		dataProvider = new ListDataProvider<Group>();

	    sotdService.retreiveAllGroups(new AsyncCallback<List<Group>>(){

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(List<Group> result) {
				dataProvider.setList(result);
				dataProvider.addDataDisplay(cellTable);
				
				//Create Columns of the table
				//Checkbox
			    CheckboxCell memberCheckBox = new CheckboxCell(true, true);
			    Column<Group, Boolean> checkColumn = new Column<Group, Boolean>(memberCheckBox) {
			 
			          @Override
			          public Boolean getValue(final Group object) {	 
			        	  String tmpUser = CurrentUser.getInstance().getCurrentUserEmail();
			        	  return object.members.contains(tmpUser);
			          }
			        };
			        
		        checkColumn.setFieldUpdater(new MemberFieldUpdater());	//Our own FieldUpdater that also updates our DataStore

				//Group
				Column<Group,String> groupColumn = new Column<Group,String>(new TextCell()) {
					@Override
					public String getValue(Group g){
						return g.groupName;
					}
				};
				groupColumn.setSortable(true);
				
				Column<Group,String> aboutColumn = new Column<Group,String>(new TextCell()) {
					@Override
					public String getValue(Group g){
						return g.groupMessage;
					}
				};
				aboutColumn.setSortable(true);
				
				Column<Group,String> establishedColumn = new Column<Group,String>(new TextCell()) {
					@Override
					public String getValue(Group g){
						
						//  Months have an 0-11 index so you have to offset them by 1.            //
						//  Years are off by 1900, so you need to offet by them 1900.  			  //
						//  ...pretty ridiculous 												  //  
						@SuppressWarnings("deprecation")
						String niceDate = (g.established.getYear() + 1900) + "/" + (g.established.getMonth() + 1) + "/" + g.established.getDate();
						return niceDate;
					}
				};
				establishedColumn.setSortable(true);
				cellTable.addColumn(checkColumn, "");
				cellTable.addColumn(groupColumn, "Group Name");
				cellTable.addColumn(aboutColumn, "About");
				cellTable.addColumn(establishedColumn, "Established");	    
			    
				allPanel.add(cellTable);
			}	
	    });
		
	    // Add a selection model so we can select cells.
//	    final SelectionModel<Group> selectionModel = new MultiSelectionModel<Group>();
//	    DefaultSelectionEventManager<Group> selectionEventManager = DefaultSelectionEventManager.<Group> createCheckboxManager(); //Hell if I know...
//	    cellTable.setSelectionModel(selectionModel,selectionEventManager);


		
		initWidget(allPanel);
	}
	
	private DialogBox createDialogBox() {
	    // Create a dialog box and set the caption text
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setText("Add a New SoTD Group");
		
		// Create a table to layout the content
		VerticalPanel dialogPanel = new VerticalPanel();
		dialogPanel.setSpacing(4);
		
		// Create a Grid for the text input and labels
		Grid newGroupGrid = new Grid(4,2);

		// Error Label
		final Label errorLabel = new Label("Fill everything out dude");
		errorLabel.setStyleName("error-label");
		errorLabel.setVisible(false);
		
		// Group Name
		Label groupNameLabel = new Label("Group Name");
		final TextBox groupNameTextBox = new TextBox();
		
		// Group Message
		Label groupMsgLabel = new Label("Group Message");
		final TextArea groupMsgTextArea = new TextArea();

		// Cancel button at the bottom of the dialog
		Button cancelButton = new Button("cancel", new ClickHandler() {
		      public void onClick(ClickEvent event) {
		        dialogBox.hide();
		      }
		    });

		// OK button, which will create the group
		Button okButton = new Button("ok", new ClickHandler() {
		      public void onClick(ClickEvent event) {	    	  
		    	String tmpName = groupNameTextBox.getText();
		    	String tmpMsg = groupMsgTextArea.getText();	    
		    	
		    	if( tmpName.isEmpty() || tmpMsg.isEmpty() ){
		    		errorLabel.setVisible(true);
		    	}
		    	else{
		    		errorLabel.setVisible(false);
		    		
		        	final Group newGroup = new Group(groupNameTextBox.getText(),
		        							   groupMsgTextArea.getText(),
		        							   new Date(),
		        							   CurrentUser.getInstance().getCurrentUserEmail());
		        	sotdService.storeGroup(newGroup, new AsyncCallback<Group>() {

						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
							
						}

						@Override
						public void onSuccess(Group result) {	
							CurrentUser.getInstance().getCurrentUser().groups.add(newGroup.groupName);
							dataProvider.getList().add(result);
							sotdService.updateDataStoreObject(CurrentUser.getInstance().getCurrentUser(), new AsyncCallback<Void>(){
								@Override
								public void onFailure(Throwable caught) {}

								@Override
								public void onSuccess(Void result) {}							
							});	
						}
		        		
		        	});
		        	dialogBox.hide();
		    	}
		      }
		    });
		
		
		//Lay all the components into the grid
		newGroupGrid.setWidget(0, 0, errorLabel);
		newGroupGrid.setWidget(1, 0, groupNameLabel);
		newGroupGrid.setWidget(1, 1, groupNameTextBox);
		newGroupGrid.setWidget(2, 0, groupMsgLabel); 
		newGroupGrid.setWidget(2, 1, groupMsgTextArea);
		newGroupGrid.setWidget(3, 0, cancelButton);
		newGroupGrid.setWidget(3, 1, okButton);
		VerticalPanel backPanel = new VerticalPanel();
		backPanel.add(newGroupGrid);
		dialogBox.setWidget(backPanel);
		
		// Return the dialog box
		return dialogBox;
	}
	
}
